#include <iostream>
#include <ctime>
#include <unistd.h>

using namespace std;

// 特殊字符：\u2588，缺点：若设置背景，字符会挡住背景
// 两种空格：\u0020 \u3000
// 相比于 #define，constexpr auto 更安全
constexpr auto BGChar = "\x1B[46m\u0020\u0020\x1B[0m";

void printTime();

int main()
{
    system("chcp 65001");
    // 通过设置行列更改cmd窗体大小
    system("@mode con cols=162 lines=16");
    system("Title clock in cmd @yzl");
    system("cls");

    // 打印当前时间
    printTime();

    return 0;
}

#pragma region 数据集

static const int one[][10] = {
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
};

static const int two[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
};

static const int three[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
};

static const int four[][10] = {
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
};

static const int five[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
};

static const int six[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
};

static const int seven[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
};

static const int eight[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
};

static const int nine[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
};

static const int zero[][10] = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
};

static const int colon[][10] = {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};

#pragma endregion

// 获取程序执行时长（秒）
static int getTimeout()
{
    return clock() / CLOCKS_PER_SEC;
}

// 获取当前时间
static tm *getTime()
{
    time_t nowtime;
    // 获取1970年1月1日0点0分0秒到现在经过的秒数
    time(&nowtime);
    // 将秒数转换为本地时间,年从1900算起,需要+1900,月为0-11,所以要+1
    tm *p = localtime(&nowtime);
    return p;
}

static void rewrite(int **arr, const int ref[][10])
{
    for (int i = 0; i < 12; i++)
    {
        arr[i] = new int[10];
        for (int j = 0; j < 10; j++)
        {
            arr[i][j] = ref[i][j];
        }
    }
}

static int **select(int num = 11)
{
    int **newArr = new int *[12];

    switch (num)
    {
    case 0:
        rewrite(newArr, zero);
        break;
    case 1:
        rewrite(newArr, one);
        break;
    case 2:
        rewrite(newArr, two);
        break;
    case 3:
        rewrite(newArr, three);
        break;
    case 4:
        rewrite(newArr, four);
        break;
    case 5:
        rewrite(newArr, five);
        break;
    case 6:
        rewrite(newArr, six);
        break;
    case 7:
        rewrite(newArr, seven);
        break;
    case 8:
        rewrite(newArr, eight);
        break;
    case 9:
        rewrite(newArr, nine);
        break;

    default:
        rewrite(newArr, colon);
        break;
    }

    return newArr;
}

static void addStr(string *str, int &i, int **arr)
{
    for (int j = 0; j < 10; j++)
    {
        *str = *str + (arr[i][j] ? BGChar : "  ");
    }

    delete arr[i];
}

static void addColon(string *str, int &i, int **colonArr)
{
    for (int j = 0; j < 10; j++)
    {
        *str = *str + (colonArr[i][j] ? BGChar : "  ");
    }
}

// 打印当前时间
void printTime()
{
    int lastTime = getTimeout();

    // 冒号
    int **sign_colon = select();

    do
    {
        int now = getTimeout();
        if (now - lastTime > 0)
        {
            tm *p = getTime();
            // printf("%04d.%02d.%02d %02d:%02d:%02d\r", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);

            const int hour = p->tm_hour,
                      min = p->tm_min,
                      sec = p->tm_sec;

            // 小时
            int **time_hour0 = select(hour / 10 % 10);
            int **time_hour1 = select(hour % 10);

            // 分钟
            int **time_min0 = select(min / 10 % 10);
            int **time_min1 = select(min % 10);

            // 秒数
            int **time_sec0 = select(sec / 10 % 10);
            int **time_sec1 = select(sec % 10);

            system("cls");
            cout << endl
                 << endl;
            for (int i = 0; i < 12; i++)
            {
                string *str = new string;

                // 时
                addStr(str, i, time_hour0);
                addStr(str, i, time_hour1);

                addColon(str, i, sign_colon);

                // 分
                addStr(str, i, time_min0);
                addStr(str, i, time_min1);

                addColon(str, i, sign_colon);

                // 秒
                addStr(str, i, time_sec0);
                addStr(str, i, time_sec1);

                cout << *str << endl;
                // 释放内存
                delete str;
            }

            lastTime = now;

            delete[] time_hour0;
            delete[] time_hour1;
            delete[] time_min0;
            delete[] time_min1;
            delete[] time_sec0;
            delete[] time_sec1;

            cout << endl;
        }

        // 暂停执行一秒
        sleep(1);
    } while (1);


    // 释放冒号内存
    for (int i = 0; i < 12; i++)
    {
        delete sign_colon[i];
    }

    delete[] sign_colon;
}